package com.example.zzpneo4j.config;

import io.minio.MinioClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.HashMap;

/**
 * MinioUtil工具类
 *
 * @author wliduo[i@dolyw.com]
 * @date 2020/2/5 17:53
 */
@Slf4j
@Component
public class MinioUtil {

    @Value("${spring.minio.bucket}")
    private String bucket;

    /**
     * minioClient
     */
    private final MinioClient minioClient;

    @Autowired
    public MinioUtil(MinioClient minioClient) {
        this.minioClient = minioClient;
    }

    /**
     * 上传文件
     *
     * @param file
     * @return java.lang.String
     * @throws
     * @author wliduo[i@dolyw.com]
     * @date 2020/2/6 16:03
     */
    public String uploadFile(MultipartFile file) {
        try (ByteArrayInputStream bais = new ByteArrayInputStream(file.getBytes())) {
            return uploadFile(bais, file.getOriginalFilename());
        } catch (IOException e) {
            log.error("{}文件上传失败", file.getOriginalFilename());
            return "";
        }
    }

    /**
     * 上传文件
     *
     * @param stream
     * @param fileName
     * @return java.lang.String
     * @throws
     * @author wliduo[i@dolyw.com]
     * @date 2020/2/6 16:04
     */
    public String uploadFile(InputStream stream, String fileName) {
        // 上传文件路径
        StringBuilder objectName = new StringBuilder();

//        String substring = fileName.substring(fileName.lastIndexOf(".") + 1);
//        objectName.append(System.currentTimeMillis()).append(".").append(substring);
        try {
            // 上传文件
            minioClient.putObject(bucket, fileName, stream, null, new HashMap<>(), null, null);
            return objectName.toString();
        } catch (Exception e) {
            log.error("{}文件上传失败", objectName);
            return "文件上传失败";
        }
    }

    /**
     * 获取文件
     *
     * @param objectName
     * @return java.io.InputStream
     * @throws
     * @author wliduo[i@dolyw.com]
     * @date 2020/2/6 16:05
     */
    public InputStream getFile(String objectName) {
        try {
            // 文件是否存在
            minioClient.statObject(bucket, objectName);
            // 获取文件
            return minioClient.getObject(bucket, objectName);
        } catch (Exception e) {
            log.error("{}文件获取失败", objectName);
            return null;
        }
    }

    /**
     * 直接下载文件
     *
     * @param res
     * @param fid
     * @param fileName
     * @return void
     * @throws
     * @author wliduo[i@dolyw.com]
     * @date 2020/3/5 9:45
     */
    public void lookUploadFile(HttpServletResponse res, String fid, String fileName) {
        try (InputStream in = this.getFile(fid);
             OutputStream output = res.getOutputStream()) {
            // 得到输入流
            if (in == null) {
                try (PrintWriter printWriter = res.getWriter()) {
                    printWriter.append("404 - File Not Exist");
                } catch (IOException e) {
                    log.error("数据异常: {}", e.getMessage());
                }
                return;
            }
            res.reset();
            res.setContentType("application/x-msdownload");
            fileName = new String(fileName.getBytes("gbk"), "iso8859-1");
            res.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            // res.setContentType(getMimeType(fileName));
            // https://gitee.com/dolyw/codes/2h1r6avwxumegjs89ztyn86
//            res.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8.name()));
//            res.setContentType("application/octet-stream");
            res.setHeader("Access-Control-Allow-Origin", "*");
            res.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            byte[] b = new byte[1024];
            int i = 0;
            while ((i = in.read(b)) > 0) {
                output.write(b, 0, i);
            }
        } catch (IOException me) {
            log.error("数据异常: {}", me.getMessage());
        }
    }

    /**
     * 获取外链
     *
     * @param objectName
     * @return java.lang.String
     * @throws
     * @author wliduo[i@dolyw.com]
     * @date 2020/2/6 16:04
     */
    public String getFileUrl(String objectName) {
        try {
            return minioClient.presignedGetObject(bucket, objectName, 60 * 60 * 24);
        } catch (Exception e) {
            log.error("{}文件获取失败", objectName);
            return "";
        }
    }
}

